/*
 * SaveSqlDB.java
 *
 * Created on April 14, 2006, 12:48 AM
 * 18, November, 2011: Adapted to use DBaseFactory and some warnings cleared.
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package portfolio;

/**
 *
 * @author ACA
 */
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.Vector;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.*;
import javax.swing.tree.*;
import java.sql.*;
import portfolio.dbHost.dataBases.DBase;
import misellanea.MiscellaneaDB;
import portfolio.dbHost.Host;
import portfolio.dbHost.dataBases.DBaseFactory;

public class SaveSqlDB extends javax.swing.JInternalFrame implements ActionListener
{
    private JTextField jtFile  = null;
    private JList      jDBList = null;
    private JTree      m_tree  = null;
    
    static String separator = "\\";     // File.separator OS dependent
                                              // default Windows separator;
    String        startDir  = "\\"; //".";

    private mainScreen mainFrame = null;

    private JTextField m_txtDir;

    private DefaultTreeModel m_model = null;

    static final String  ACTION_UP     = "vkAction_UP";
    static final String  ACTION_SELECT = "vkAction_Select";
    static final String  ACTION_CANCEL = "vkAction_Cancel";
    /***************************************************************************/
    class SelDirExpansionListener implements TreeExpansionListener
    {
        public void treeExpanded(TreeExpansionEvent event)
        {
            DefaultMutableTreeNode node = 
                    (DefaultMutableTreeNode)(event.getPath().getLastPathComponent());
            if (node != null) {
                MyNode nd = (MyNode)(node.getUserObject());
                expandDir (node, new File (nd.m_fullName));
            }
        } /* end method treeExpanded */
        /**********************************************************************/
        public void treeCollapsed(TreeExpansionEvent event) {}  // Don't care
    } /* end class SelDirExpansionListener */    
    /***************************************************************************/
    class listMouseListener implements MouseListener
    {
        private SaveSqlDB mainFrame = null;
        
        public listMouseListener (SaveSqlDB mainFrameParam)
        {
            mainFrame = mainFrameParam;
            return;
        }

        public void mouseClicked (MouseEvent evt) 
        {
            if (evt.getClickCount() == 2) {          // Double-click
                    // Get item index
                    //int index = list.locationToIndex(evt.getPoint());
                //System.out.println ("Mouse clicked");

                String sSelectedDB = mainFrame.getList().getSelectedValue().toString();
                String sPath       = null;
                if (sSelectedDB != null) {
                    String sTmpText = mainFrame.getTextField().getText();
                    if (sTmpText != null) {
                        if (sTmpText.endsWith (separator)) {
                            sPath = sTmpText + sSelectedDB;
                        } else {
                            sPath = sSelectedDB;
                        }
                    }  else {
                        sPath = sSelectedDB;
                    }                  
                    mainFrame.getTextField().setText(sPath); //sSelectedDB);
                }
            }
        } /* end method mouseClicked */        

        public void mousePressed  (MouseEvent e) { }
        public void mouseReleased (MouseEvent e) { }
        public void mouseEntered  (MouseEvent e) { }
        public void mouseExited   (MouseEvent e) { }
    } /* end class listMouseListener */
    /***************************************************************************/
    class treeMouseListener implements MouseListener
    {
        private SaveSqlDB mainFrame = null;

        public treeMouseListener (SaveSqlDB mainFrameParam)
        {
            mainFrame = mainFrameParam;
        }
        /*************************************************************************/
        public void mouseClicked (MouseEvent evt) 
        {
            if (evt.getClickCount() == 1) {          // Double-click
                    // Get item index
                    //int index = list.locationToIndex(evt.getPoint());
                System.out.println ("Mouse clicked 1");
                
                JTree tmpTree = (JTree) evt.getComponent();
                int selRow = tmpTree.getRowForLocation(evt.getX(), evt.getY());
                TreePath selPath = tmpTree.getPathForLocation(evt.getX(), evt.getY());
                if (selRow != -1) {
                    Object [] oTmpPath = selPath.getPath();
                    if (oTmpPath.length > 0) {
                        String sPath = null;
                        for (int iIdx = 0; iIdx < oTmpPath.length; iIdx++) {
                            sPath =(sPath == null)? oTmpPath[iIdx].toString() + separator: 
                                                    sPath + oTmpPath[iIdx].toString() + separator;
                        }
                        String sTmpText = mainFrame.getTextField().getText();

                        if (sTmpText != null) {
                            int iSeparator = sTmpText.lastIndexOf(separator);
                            int iLen       = sTmpText.length();
                            if (iSeparator != -1) {
                                if (iSeparator != iLen -1) {
                                    sPath = sPath + sTmpText.substring(iSeparator +1);
                                }
                            } else {
                                sPath = sPath + sTmpText;
                            }
                        }
                        mainFrame.getTextField().setText(sPath);
                    } else {
                        //Error
                    }
                } else {
                    // Error
                }

            }
        } /* end method mouseCliked */
        /*************************************************************************/
        private String getPath (String sDir) 
        {
            File dir = new File (sDir);
            String sFull = dir.getAbsolutePath();
            if (sFull.endsWith("."))
                sFull = sFull.substring(0, sFull.length()-1);
            if (!sFull.endsWith(separator))
                sFull += separator;
            return sFull;        
        }            

        public void mousePressed  (MouseEvent e) { }
        public void mouseReleased (MouseEvent e) { }
        public void mouseEntered  (MouseEvent e) { }
        public void mouseExited   (MouseEvent e) { }
    } /* end class treeMouseListener */
    /***************************************************************************/
        public void actionPerformed (ActionEvent evt) 
        {
            String sActionCommand = evt.getActionCommand ();
            MyNode nd;
            
            if (sActionCommand.equals (this.ACTION_UP)) {
                DefaultMutableTreeNode top = 
                        (DefaultMutableTreeNode)  m_model.getRoot ();
                nd = (MyNode) top.getUserObject ();
                String str = nd.m_fullName;
                if (str.endsWith (separator))
                    str = str.substring (0, str.length () - separator.length ());
                int index = str.lastIndexOf (separator);
                if (index >= 0)
                    str = str.substring (0, index+separator.length());
                File dir = new File (str);

                nd = getDirName (dir);
                top = new DefaultMutableTreeNode (nd);
                top.add (new DefaultMutableTreeNode ( new Boolean(true) ));
                expandDir (top, dir);

                m_model = new DefaultTreeModel (top);
                m_tree.setModel (m_model);                
            } else if (sActionCommand.equals (this.ACTION_SELECT)) {
               String sTemp     = jtFile.getText();
               String sPath     = null;
               String sDatabase = null;
   
                if (sTemp != null) {
                    int iSeparator = sTemp.lastIndexOf(separator);
                    int iLen       = sTemp.length();
                    if (iSeparator != -1) {
                        if (iSeparator != iLen -1) {
                            sPath     = sTemp.substring (0, iSeparator +1); 
                            sDatabase = sTemp.substring (iSeparator +1);
                        } else {
                            sPath = sTemp;
                            sDatabase = null;
                        }
                    } else {
                        sDatabase = sTemp;
                        sPath = null;
                    }
                }
                if (sDatabase != null) {
                    try {
                        String sFileName         =  sPath + sDatabase + ".sql";                   
                        File outFile             = new File (sFileName);
                        boolean bSuccess         = outFile.createNewFile ();
                        if (bSuccess == false) {
                            throw new Exception ("File already exists.");
                        }
                        BufferedWriter outFileWriter   = new BufferedWriter (new FileWriter (outFile));
                    
//                        Connection connection = mainFrame.getDBLoggedHost().getConnection();
                        Host dbHost = mainFrame.getDBLoggedHost();
                        Connection connection = dbHost.getConnection();
                        
                        try {
////                            DBase  dBase = new DBase (mainFrame, connection, sDatabase);
//                            DBase dBase = new DBase (dbHost, sDatabase);
                            DBaseFactory dbFactory = new DBaseFactory ();
                            DBase dBase = dbFactory.getDBType(dbHost, sDatabase);
                            MiscellaneaDB.saveDBtoFile(connection, dBase, outFileWriter, sDatabase);
                        }
                        catch (Exception exp) {
                            outFile.delete();
                            outFileWriter.close();
                            throw new Exception (exp);
                        }
                        outFileWriter.close ();
                    } catch (Exception ex) {
                        mainFrame.displayMessage("SaveSqlDB.actionPerformed 240", ex.toString());
                    }
                } else {
                    mainFrame.displayMessage ("SaveSqlDB.actionPerformed 243", "No Database selected for saving.");
                }
               
                
                dispose();                
            } else if (sActionCommand.equals (this.ACTION_CANCEL)) {
                this.dispose ();
            }
        } /* end method actionPerformed */
        /***************************************************************************/
	public SaveSqlDB (mainScreen       mainFrameParam, 
                          JTextField       txtDir, 
                          Vector           vListParam,
                          String           sSeparatorParam)
	{
            super ("Save SQL DB.", true, true, false, false);
            mainFrame = mainFrameParam;
            separator = sSeparatorParam;
            
            this.getContentPane ().setLayout (new BorderLayout ());
            mainFrame.getLayeredPane ().add (this);
            
            JPanel northPanel = new JPanel ();
            northPanel.setBorder (new EmptyBorder (5, 5, 0, 5));
            northPanel.setLayout (new BoxLayout (northPanel, BoxLayout.X_AXIS));
            JLabel fileLabel = new JLabel ("Target file: ");
            northPanel.add (fileLabel);
            jtFile = new JTextField ();
            northPanel.add (jtFile);
            this.getContentPane ().add ("North", northPanel);

            m_txtDir = txtDir;

            JPanel p = new JPanel ( );
            p.setLayout(new BoxLayout (p, BoxLayout.X_AXIS));
            p.setBackground (Color.lightGray);
            JButton btnUpOne = new JButton ("Up");
            btnUpOne.addActionListener (this);
            btnUpOne.setActionCommand (SaveSqlDB.ACTION_UP);
            p.add(btnUpOne);

            JButton btnSelect = new JButton ("Select");
            btnSelect.addActionListener (this);
            btnSelect.setActionCommand (SaveSqlDB.ACTION_SELECT);
            p.add(btnSelect);

            JButton btnCancel = new JButton("Cancel");
            btnCancel.addActionListener (this);
            btnCancel.setActionCommand (SaveSqlDB.ACTION_CANCEL);
            p.add (btnCancel);
            this.getContentPane ().add ("South", p);

            JPanel centerPanel = new JPanel (new GridLayout (1, 2));
            centerPanel.setBorder(new EmptyBorder (5, 5, 5, 5));
            
            JPanel panelList       = new JPanel ();
            panelList.setLayout(new BoxLayout (panelList, BoxLayout.Y_AXIS));
            JLabel listLabel       = new JLabel ("Data base list.");
            panelList.add(listLabel);
            jDBList                = new JList (vListParam);
            jDBList.addMouseListener (new listMouseListener (this));
            JScrollPane scrollList = new JScrollPane (jDBList);
            panelList.add(scrollList);
            
            if (m_txtDir != null && m_txtDir.getText().length() > 0)
                    startDir = m_txtDir.getText ();
            File rootDir = new File (startDir);

            MyNode nd = getDirName (rootDir);
            DefaultMutableTreeNode top = new DefaultMutableTreeNode (nd);
            top.add (new DefaultMutableTreeNode ( new Boolean(true) ));
            expandDir (top, rootDir);

            m_model = new DefaultTreeModel (top);
            m_tree  = new JTree(m_model);
            m_tree.addTreeExpansionListener (new SelDirExpansionListener ());
            m_tree.addMouseListener (new treeMouseListener (this));
            JPanel      panelTree = new JPanel ();
            panelTree.setLayout (new BoxLayout (panelTree, BoxLayout.Y_AXIS));
            JLabel treeLabel = new JLabel ("Directory tree.");
            panelTree.add (treeLabel);
            JScrollPane scrollTree = new JScrollPane ();
            scrollTree.getViewport ().add (m_tree);

            m_tree.getSelectionModel ().setSelectionMode (TreeSelectionModel.SINGLE_TREE_SELECTION);
            panelTree.add (scrollTree);
            
            centerPanel.add (panelTree);
            centerPanel.add (panelList);

            this.getContentPane().add ("Center", centerPanel);
            
            this.setBounds (0, 100, 300, 305);
            Dimension mainDim = mainFrame.getSize ();
            Dimension thisDim = this.getSize ();
            int iXLocation = (mainDim.width / 2)  - (thisDim.width / 2);
            int iYLocation = (mainDim.height / 2) - (thisDim.height / 2);
            this.setLocation (iXLocation, iYLocation);
          
            this.show ();
	} /* end constructor SaveSqlDB */        
        /************************************************************************/
	protected void expandDir (DefaultMutableTreeNode parent, File dir)
	{
            DefaultMutableTreeNode flag = 
                    (DefaultMutableTreeNode) parent.getFirstChild ();
            if (flag == null)	  // No flag
                    return;
            Object obj = flag.getUserObject();
            if (obj instanceof Boolean)
                 parent.removeAllChildren();  // Flag is found
            else
                return;      // Already expanded

            String path     = getPath (dir);
            String [] files = dir.list ();
            
            if (files == null)
                return;
            Vector list = new Vector();
            int i, k;

            for ( k = 0; k < files.length; k++) {
                File f = new File (path + files [k]);
                
                if (f.isDirectory()) {
                    MyNode newNode = new MyNode(files[k], getPath (f));

                    //  Store in ABC order
                    boolean isAdded = false;
                    for (i=0; i<list.size (); i++) {
                        MyNode nd = (MyNode) list.elementAt (i);
                        if (newNode.compareTo (nd) < 0) {
                            list.insertElementAt(newNode, i);
                            isAdded = true;
                            break;
                        }
                    }
                    if (!isAdded) {
                        list.addElement (newNode);
                    }
                }
            }

            for (i=0; i < list.size (); i++) {
                MyNode nd = (MyNode)list.elementAt (i);
                DefaultMutableTreeNode node = new DefaultMutableTreeNode(nd);
                parent.add (node);

                if (hasSubDirs (nd.m_fullName))
                    node.add (new DefaultMutableTreeNode ( new Boolean(true) ));	//  Set flag
            }

            if (m_tree != null)
                m_model.reload (parent);

	} /* end method expandDir */
        /************************************************************************/
	protected boolean hasSubDirs(String fullPath)
	{
            File dir = new File(fullPath);
            String[] files = dir.list();
            String path = getPath(dir);
            for (int k = 0; k < files.length; k++) {
                File f = new File (path+files [k]);
                if (f.isDirectory ())
                    return true;
            }
            return false;
	} /* end method hasSubDirs */
        /************************************************************************/
	protected static String getPath(File dir)
	{
            String sFull = dir.getAbsolutePath();
            if (sFull.endsWith("."))
                sFull = sFull.substring(0, sFull.length()-1);
            if (!sFull.endsWith(separator))
                sFull += separator;
            return sFull;
	} /* end method getPath */
        /************************************************************************/
	protected static MyNode getDirName (File dir)
	{
            String sFull = getPath (dir);
            String str = sFull;
            if (str.endsWith (separator))
                str = str.substring (0, str.length () - separator.length ());
            int index = str.lastIndexOf (separator);
            if (index >= 0)
                str = str.substring (index+separator.length(), str.length());
            return new MyNode(str, sFull);
	} /* end method getDirName */
        /*************************************************************************/
        public JList getList ()
        {
            return jDBList;
        }
        /*************************************************************************/
        public JTextField getTextField ()
        {
            return jtFile;
        }
        /*************************************************************************/
        public JTree getTree ()
        {
            return m_tree;
        }
} /* end class SaveSqlDB */
/**********************************************************************************/
/**********************************************************************************/
class MyNode extends Object
{
	String m_shortName = "";
	String m_fullName  = "";
        /************************************************************************/
	public MyNode(String shortName, String fullName)
	{
            m_shortName = shortName;
            m_fullName  = fullName;
	} /* end method MyNode */
        /***********************************************************************/
	public int compareTo(MyNode toCompare)
	{ 
            return  m_shortName.compareTo( toCompare.m_shortName ); 
        } /* end method compareTo */
        /************************************************************************/
	public String toString() { 
            return m_shortName; 
        } /* end method toString */
} /* end class MyNode */
